<template>
  <div v-loading="loading">
    <el-table :data="tableData" ref="elPlusTable" @header-contextmenu="headerClick" @selection-change="handleSelectionChange" @sort-change="getsortList" :show-summary="cTableOpt.summary" :summary-method="getSummaries" :row-key="cTableOpt.rowKey ? cTableOpt.rowKey : 'id'" :tree-props="cTableOpt.treeProps" @expand-change="expandChange" @cell-click="cellClick">
      <el-table-column type="expand" v-if="cTableOpt.expand">
        <template #default="form">
          <slot name="expandColumne" :form="form"></slot>
        </template>
      </el-table-column>
      <el-table-column v-if="cTableOpt.selection" type="selection" width="55" />
      <template v-for="(column, index) in cTableOpt.columns" :key="'C' + index">
        <Column :column="column">
          <template #otherColumn="{ row, column, index }">
            <slot name="otherColumn" :row="row" :column="column" :index="index"></slot>
          </template>
        </Column>
      </template>
      <slot name="otherColumned"></slot>
      <el-table-column label="操作" :width="cTableOpt.btnWidth || 250" align="center" v-if="!cTableOpt.noBtn">
        <template #default="scope">
          <div class="buttonColumn">
            <el-button v-if="cTableOpt.release?.url" :type="getReleaseItem(scope.row).btnType" @click="release(scope.row)"> {{ getReleaseItem(scope.row).showMsg }} </el-button>
            <slot name="otherBtn" :row="scope.row" :index="scope.$index"></slot>
            <el-button type="primary" v-if="!cTableOpt.hideEdit" @click="editRow(scope.row)">编辑</el-button>
            <el-button type="danger" v-if="cTableOpt.delete" @click="delFn(scope.row, scope.$index)">{{ cTableOpt.delete?.deleteTxt || "删除" }}</el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination" v-if="!cTableOpt.noPage">
      <slot name="simplePage" v-if="cTableOpt.simplePage"></slot>
      <el-pagination v-else v-model:currentPage="currentPage" :page-sizes="cTableOpt.pageSizes || [5, 10, 30, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange"> </el-pagination>
    </div>
    <el-dialog title="提示" v-model="delVisible" width="30%">
      <div class="del-dialog-cnt" style="font-size: 16px">是否确定删除？</div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="delVisible = false">取 消</el-button>
          <el-button type="primary" @click="deleteFn">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import Column from "./column.vue";
interface CtablePropsType {
  cTableOpt: CTableOptType;
  id?: string;
}
const props = defineProps<CtablePropsType>();
const emit = defineEmits(["expandChange", "cellClick", "showAdd", "beforeJump", "beforeGetListFn", "afterGetData", "deleteAfter", "deleteColumn"]);
const loading = ref(false);
const tableData = ref([]);
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0);
const pages = ref(0);
const delVisible = ref(false);
const multipleSelection = ref<any[]>([]);
const router = useRouter();
const moreParams = ref(null);
if (props.cTableOpt.pageSize) pageSize.value = props.cTableOpt.pageSize;
const editRow = (row: any) => {
  if (props.cTableOpt.jumpAdd) {
    emit("beforeJump", row);
    router.push(`${props.cTableOpt.detailPage}/${row.id}`);
  }
  nextTick(() => {
    return emit("showAdd", { row });
  });
};
function cellClick(row, column, cell, event) {
  return emit("cellClick", { row, column, cell, event });
}
function expandChange(row, expanded) {
  return emit("expandChange", { row, expanded });
}

const elPlusTable = ref(null);
const handleSelectionChange = (val: any[]) => {
  let arr: any[] = [];
  val.map((item) => {
    props.cTableOpt.selectionId ? arr.push(item) : arr.push(item.id);
  });
  multipleSelection.value = arr;
};
const handleSizeChange = (value: number) => {
  pageSize.value = value;
  getListFn(moreParams.value);
};
const handleCurrentChange = (value: number) => {
  currentPage.value = value;
  getListFn(moreParams.value);
};
const getListFn = async (e: any, dom?: string) => {
  loading.value = false;
  let obj = {};
  if (props.cTableOpt.list?.params) obj = Object.assign(obj, props.cTableOpt.list?.params);
  if (dom) currentPage.value = 1;
  if (!props.cTableOpt.noPage) obj = Object.assign(obj, { limit: pageSize.value, start: currentPage.value - 1 });
  if (e) {
    moreParams.value = e;
    obj = Object.assign(obj, e);
  }
  let objed: { [key: string]: any } = {};
  for (let item in obj) {
    if (obj[item as keyof typeof obj] || item == "start") objed[item] = obj[item as keyof typeof obj];
  }
  if (props.cTableOpt.beforeGetList) emit("beforeGetListFn", obj);
  let res = await hfoRequest.get({ url: props.cTableOpt.list?.url, params: objed });
  if (res) {
    if (!props.cTableOpt.noPage) {
      total.value = res.data.total;
      pages.value = res.data.total / pageSize.value;
    }
    if (props.cTableOpt.afterGetData) {
      emit("afterGetData", res);
    } else {
      tableData.value = res.data.dataList;
    }
  }
  loading.value = false;
};
function getReleaseItem(row) {
  let stateKey = row[props.cTableOpt.release?.props];
  return props.cTableOpt.release.releaseItem.find((item) => {
    return item.state == stateKey;
  });
}
const release = async (row: any) => {
  let res = await hfoRequest.put({ url: props.cTableOpt.release?.url, data: row });
  if (res) {
    ElMessage.success(getReleaseItem(row).changeMsg);
    getListFn(moreParams.value);
  }
};
function initiazaRelease() {
  if (props.cTableOpt.release) {
    let obj = props.cTableOpt.release;
    if (!obj.releaseItem)
      obj.releaseItem = [
        { state: true, changeMsg: "下架成功", showMsg: "上架", btnType: "primary" },
        { state: false, changeMsg: "上架成功", showMsg: "下架", btnType: "danger" }
      ];
    if (!props.cTableOpt.release?.props) props.cTableOpt.release.props = "state";
  }
}
initiazaRelease();
const rowInfo = ref<{ id?: string }>({});
const delFn = (row: any, index: number) => {
  if (!row.id) {
    tableData.value.splice(index, 1);
    return;
  }
  delVisible.value = true;
  rowInfo.value = row;
};
const deleteFn = async () => {
  if (!props.cTableOpt.delete) return;
  let res = await hfoRequest.delete({ url: `${props.cTableOpt.delete?.url}/${rowInfo.value.id}` });
  if (res.flag) {
    ElMessage.success("删除成功");
    getListFn(moreParams.value);
    if (props.cTableOpt.delete?.deleteAfter) emit("deleteAfter");
    delVisible.value = false;
  }
};

const headerClick = (column: { property: string }, event: MouseEvent) => {
  let obj = { x: event.clientX, y: event.clientY };
  emit("deleteColumn", { obj, column: column.property });
};
const getSummaries = ({ columns, data }: { columns: { property: string }[]; data: any }) => {
  const sums: string[] = [];
  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = "合计";
      return;
    }
    const values = data.map((item) => Number(item[column.property]));
    let setting = props.cTableOpt.columns.filter((item) => {
      return item.noSum;
    });
    if (!values.every((value) => Number.isNaN(value)) && column.property != setting[0]?.prop) {
      sums[index] = `${values.reduce((prev, curr) => {
        const value = Number(curr);
        if (!Number.isNaN(value)) {
          return parseFloat((prev + curr).toFixed(2));
        } else {
          return prev;
        }
      }, 0)}`;
    } else {
      sums[index] = "N/A";
    }
  });
  return sums;
};
const getsortList = ({ prop, order }: { prop: string; order: "descending" | "ascending" }) => {
  getListFn(moreParams.value);
};
onMounted(() => {
  if (!props.cTableOpt.noData && props.cTableOpt.list?.url) getListFn(null);
});
defineExpose({
  getListFn,
  tableData
});
</script>

<style lang="scss" scoped>
.pagination {
  margin: 20px 0;
  text-align: right;
}
.buttonColumn .el-button {
  margin-bottom: 10px;
}
</style>
